﻿/*=============================================================================
* File Name : Vector4.h                         Ver : 1.00  Date : 2009-3-20
*
* Description :
*
*       4Dベクトル計算　ヘッダ
*
* Author : 土田　悠貴.
*============================================================================*/
#ifndef _VECTOR4_H_
#define _VECTOR4_H_

namespace tglib
{

class Vector2;
class Vector3;
class Matrix4;

/**
 * @brief 4Dベクトル計算クラス．
 */
class Vector4
{
public:
	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 */
	Vector4();

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in] X　x座標．
	 * @param [in] Y　y座標．
	 * @param [in] Z　z座標．
	 * @param [in] W　w座標．
	 */
	Vector4( float X, float Y, float Z, float W );

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in] v2　2Dベクトル．
	 * @param [in] Z　 Z座標．
	 * @param [in] W　 w成分．
	 */
	Vector4( const Vector2& v2, float Z = 0.0f, float W = 0.0f );

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in] v3　3Dベクトル．
	 * @param [in] W　 w成分．
	 */
	Vector4( const Vector3& v3, float W = 0.0f );

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in] p　配列のポインタ．
	 */
	Vector4( const float* p );

	/*===========================================================================*/
	/**
	 * 正規化．
	 *
	 * @return 正規化したベクトル．
	 */
	Vector4& normalize();

	/*===========================================================================*/
	/**
	 * 正規化したベクトルを取得する．
	 *
	 * @return 正規化したベクトル．
	 */
	Vector4 getNormalized() const;

	/*===========================================================================*/
	/**
	 * 長さを求める．
	 *
	 * @return 長さ ．
	 */
	float length() const;

	/*===========================================================================*/
	/**
	 * 長さを求める (２乗和のみ）．
	 *
	 * @return 長さ(２乗和）．
	 */
	float lengthSq() const;

	/*===========================================================================*/
	/**
	 * 距離を求める．
	 *
	 * @param [in]  V 4Dベクトル ．
	 * @return 距離 ．
	 */
	float distance( const Vector4& V ) const;

	/*===========================================================================*/
	/**
	 * 内積を求める．
	 *
	 * @param [in]  V 4Dベクトル ．
	 * @return 内積 ．
	 */
	float dot( const Vector4& V ) const;

	/*===========================================================================*/
	/**
	 * 小さい要素を求める．
	 *
	 * @param [in]  V 4Dベクトル ．
	 * @return 小さい要素 ．
	 */
	Vector4 minimize( const Vector4& V ) const;

	/*===========================================================================*/
	/**
	 * 大きい要素を求める．
	 *
	 * @param [in]  V 4Dベクトル ．
	 * @return 大きい要素 ．
	 */
	Vector4 maximize( const Vector4& V ) const;

	/*=========================================================================*/
	/**
	 * @brief ベクトルの線形補間を行う
	 * 
	 * @param [in] min 最小値.
	 * @param [in] max 最大値.
	 * @param [in] t 補間値( 0.0f～1.0f ).
	 * @return 結果のベクトル.
	 */
	Vector4& lerp( const Vector4& min, const Vector4& max, float t );

	/*===========================================================================*/
	/**
	 * 二次補間を行う．
	 *
	 * @param [in]  v1 補間要素4次元ベクトル.
	 * @param [in]  v2 補間要素4次元ベクトル.
	 * @param [in]  v3 補間要素4次元ベクトル.
	 * @param [in]  t 補間値( 0.0f～1.0f ).
	 * @return 補間した3Dベクトル ．
	 */
	Vector4& quadratic(const Vector4& v1, const Vector4& v2, const Vector4& v3, float t);

	/*===========================================================================*/
	/**
	 * (+)単項演算子オーバーロード．
	 *
	 * @return 結果のVector4．
	 */
	Vector4 operator + () const;

	/*===========================================================================*/
	/**
	 * (-)単項演算子オーバーロード．
	 *
	 * @return 結果のVector4.
	 */
	Vector4 operator - () const;

	/*===========================================================================*/
	/**
	 * (+=) 演算子オーバーロード．
	 * 
	 * @param [in]  v Vector4．
	 * @return 結果のVector4．
	 */
	Vector4& operator += ( const Vector4& v );

	/*===========================================================================*/
	/**
	 * (-=) 演算子オーバーロード．
	 * 
	 * @param [in]  v Vector4．
	 * @return 結果のVector4．
	 */
	Vector4& operator -= ( const Vector4& v );

	/*===========================================================================*/
	/**
	 * (*=) 演算子オーバーロード．
	 * 
	 * @param [in]  v Vector4．
	 * @return 結果のVector4．
	 */
	Vector4& operator *= ( const Vector4& v );

	/*===========================================================================*/
	/**
	 * (/=) 演算子オーバーロード．
	 * 
	 * @param [in]  v Vector4．
	 * @return 結果のVector4．
	 */
	Vector4& operator /= ( const Vector4& v );

	/*===========================================================================*/
	/**
	 * (*=) 演算子オーバーロード．
	 * 
	 * @param [in]  s スカラー．
	 * @return 結果のVector4．
	 */
	Vector4& operator *= ( float s );

	/*===========================================================================*/
	/**
	 * (/=) 演算子オーバーロード．
	 * 
	 * @param [in]  s スカラー．
	 * @return 結果のVector4．
	 */
	Vector4& operator /= ( float s );

public:

	/** @brief x座標 */
	float x;	

	/** @brief y座標 */
	float y;	

	/** @brief z座標 */
	float z;	

	/** @brief スカラー値 */
	float w;	
};

/***  以下非メンバ関数 *******************************************************/

/*===========================================================================*/
/**
 * (+)演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 結果のVector4．
 */
const Vector4 operator + ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (-)演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 結果のVector4．
 */
const Vector4 operator - ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (*)演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 結果のVector4．
 */
const Vector4 operator * ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (*)演算子オーバーロード．
 * 
 * @param [in]  v Vector4．
 * @param [in]  s スカラー．
 * @return 結果のVector4．
 */
const Vector4 operator * ( const Vector4& v, const float s );

/*===========================================================================*/
/**
 * (*)演算子オーバーロード．
 * 
 * @param [in]  s スカラー．
 * @param [in]  v Vector4．
 * @return 結果のVector4．
 */
const Vector4 operator * ( const float s, const Vector4& v );

/*===========================================================================*/
/**
 * (/)演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 結果のVector4．
 */
const Vector4 operator / ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (/)演算子オーバーロード．
 * 
 * @param [in]  v Vector4．
 * @param [in]  s スカラー．
 * @return 結果のVector4．
 */
const Vector4 operator / ( const Vector4& v, float s );

/*===========================================================================*/
/**
 * (/)演算子オーバーロード．
 * 
 * @param [in]  s スカラー．
 * @param [in]  v Vector4．
 * @return 結果のVector4．
 */
const Vector4 operator / ( float s, const Vector4& v );

/*===========================================================================*/
/**
 * (==) 演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 比較結果．
 */
bool operator == ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (!=) 演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 比較結果．
 */
bool operator != ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (<) 演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 比較結果．
 */
bool operator < ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (>) 演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 比較結果．
 */
bool operator > ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (<=) 演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 比較結果．
 */
bool operator <= ( const Vector4& v1, const Vector4& v2 );

/*===========================================================================*/
/**
 * (>=) 演算子オーバーロード．
 * 
 * @param [in]  v1 Vector4．
 * @param [in]  v2 Vector4．
 * @return 比較結果．
 */
bool operator >= ( const Vector4& v1, const Vector4& v2 );

} // namespace tglib

#endif

/*========= End of File =====================================================*/
